package com.zzq.my.jetpacks.jectpackapp.utils;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.TextUtils;
import android.webkit.URLUtil;

import androidx.annotation.NonNull;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 描述：附件下载封装了一个工具类
 * 点击的时候；第一次如果没有则下载保存本地；并直接打开
 * 如果已经下载过了； 第二次，直接加载显示
 * 作者：zhuangzeqin
 * 时间: 2018年9月12日15:34:13
 * 邮箱：zzq@eeepay.cn
 * 备注:
 */
public final class FileAsyncDownloadBuilder {
    //创建文件夹 sdb_DownLoad，在存储卡下"eeepay_v2"
    private String dirName = Environment.getExternalStorageDirectory() + "/sdb_DownLoad/";
//    private String dirName = ABFileUtil.SD_CARD_PATH + "/eeepay_v2/";
    private Object mTag;//设置请求的tag
    private String mDownloadUrl;//附件下载地址
    private String mFileName;//文件名
    public Context mContext;

    private ResultCallBack resultCallBack;//设置监听接口

    private FileAsyncDownloadBuilder(Builder builder) {
        this.mTag = builder.tag;
        this.mDownloadUrl = builder.downloadUrl;
        this.mFileName = builder.fileName;
        this.mContext = builder.mContext;
        this.resultCallBack = builder.resultCallBack;
        //创建目录
        createFileDirs();
    }

    /**
     * 创建目录
     */
    private void createFileDirs() {
        File file = new File(dirName);
        //不存在创建
        if (!file.exists()) {
            file.mkdirs();//创建目录
        }
    }

    /**
     * 获取Builder 实例
     *
     * @return
     */
    public static Builder with(Context mContext) {
        return new Builder(mContext);
    }

    public static class Builder {
        private Object tag;//设置请求的tag
        private String downloadUrl;//附件下载地址
        private String fileName;//文件名
        public Context mContext;
        private ResultCallBack resultCallBack;//设置监听接口

        public Builder(Context mContext) {
            this.mContext = mContext;
        }

        public Builder setTag(Object tag) {
            this.tag = tag;
            return this;
        }

        public Builder setResultCallBack(ResultCallBack resultCallBack) {
            this.resultCallBack = resultCallBack;
            return this;
        }

        public Builder setDownloadUrl(@NonNull String downloadUrl) {
            this.downloadUrl = downloadUrl;
            return this;
        }

        public Builder setFileName(@NonNull String fileName) {
            this.fileName = fileName;
            return this;
        }

        /**
         * 静态内部类调用外部类的构造函数，来构造外部类
         * Builder类中的成员函数返回Builder对象自身的另一个作用就是让它支持链式调用，使代码可读性大大增强。
         *
         * @return
         */
        public FileAsyncDownloadBuilder build() {
            return new FileAsyncDownloadBuilder(this);
        }
    }

    /**
     * 开始请求数据
     */
    public void start() {
        if (TextUtils.isEmpty(mFileName))
            throw new IllegalStateException("===mFileName is null===");
        if (TextUtils.isEmpty(mDownloadUrl))
            throw new IllegalStateException("===mDownloadUrl is null===");
        if (!URLUtil.isNetworkUrl(mDownloadUrl))
            throw new IllegalStateException(mDownloadUrl + "===The url is Illegal address.===");
        boolean result = checkResult(mFileName);
        if (result)//如果存在直接启动
            CallOtherOpeanFileUtils.openFile(mContext, new File(dirName, mFileName));
        else//否则开始下载
            new downloadAsyncTask().execute(mDownloadUrl, mFileName);

    }

    /**
     * ------注释说明---异步下载文件-----
     **/
    class downloadAsyncTask extends AsyncTask<String, Void, String> {
        //onPreExecute用于异步处理前的操作
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        //在doInBackground方法中进行异步任务的处理.
        @Override
        protected String doInBackground(String... strings) {
            String downloadUrl = strings[0];
            String fileName = strings[1];
            download(downloadUrl);
            return fileName;
        }

        //onPostExecute用于UI的更新.此方法的参数为doInBackground方法返回的值.
        @Override
        protected void onPostExecute(String fileName) {
            super.onPostExecute(fileName);
            boolean result = checkResult(fileName);
            if (result) {
                if (resultCallBack != null) {
                    resultCallBack.onSucess(fileName);
                } else {
                    CallOtherOpeanFileUtils.openFile(mContext, new File(dirName, fileName));
                }
            } else {
                System.out.println( "载失败，请稍后重试！！！");
//                Toast.makeText(mContext, "下载失败，请稍后重试.", Toast.LENGTH_SHORT).show();
            }

        }
    }

    //下载具体操作
    private void download(@NonNull String downloadUrl) {
        BufferedInputStream bis = null;//输入流的缓冲区
        try {
            URL url = new URL(downloadUrl);
            //打开连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept-Encoding", "identity");
            conn.setRequestProperty("User-Agent", " Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36");
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(15000);
            conn.connect();
            //打开输入流
            InputStream is = conn.getInputStream();
            bis = new BufferedInputStream(is);
            //获得长度
            int contentLength = conn.getContentLength();
//            long contentLength = getContentSize(conn);
//            Log.e(TAG, "contentLength = " + contentLength);
            //下载后的文件名
//            String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1);
            File file1 = new File(dirName, mFileName);
            if (file1.exists()) {
                file1.delete();//存在；先删除掉
            }
            file1.createNewFile();//创建一个新的文件
            //获取服务器回馈的状态码
            int code = conn.getResponseCode();
            // 如果响应成功200
            if (code== HttpURLConnection.HTTP_OK) {
                //创建字节流
                byte[] bs = new byte[4 * 1024];
                int len;
                //获取输出对象,参数一：目标文件，参数2表示在原来的文件中追加
                OutputStream os = new BufferedOutputStream(new FileOutputStream(file1));
                //写数据
                while ((len = bis.read(bs)) != -1) {
                    os.write(bs, 0, len);
                }
                //完成后关闭流
                os.flush();
                os.close();
                bis.close();
                System.out.println(code + "：下载完成！！！");
            }
            else
            {
                System.out.println(code + "：下载失败！！！");
            }
            //断开连接
            conn.disconnect();
        } catch (Exception e) {
            System.out.println("下载失败！！！");
            e.printStackTrace();
        }
    }

    /**
     * 检查文件是否存在指定的目录
     *
     * @param fileName
     * @return
     */
    private boolean checkResult(String fileName) {
        File file = new File(dirName);
        boolean ischeck = false;
        String[] list = file.list();
        for (int i = 0; i < list.length; i++) {
            if (list[i].equals(fileName)) {
                ischeck = true;
                break;
            }
        }
        return ischeck;
    }

    /**
     * 提供外围接口；通过接口回传
     */
    public interface ResultCallBack {
        void onSucess(String fileName);//成功返回文件成功
    }
}
